package com.demo.android.backby;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringBufferInputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class BackbyActivity extends Activity {
	/** Called when the activity is first created. */
	String FILENAME = "response_xml";
	XMLReader xr;
	DataHandler dataHandler = new DataHandler(); 
	private static final boolean DEBUG = true;
	public class BContext extends Object{
		public String resultid; 
		public String sessionid; 
		
		/*Storage Info*/
		public String email; 
		public String limit_storage; 
		public String storage_used; 
		public String limit_uploadspeed;
		public String status; 

		/* upload, download */
		public String fhandle; 
		public void updateData(BContext ndata){
			if(null != ndata.resultid)	resultid = ndata.resultid;
			if(null != ndata.sessionid)	sessionid = ndata.sessionid;
			if(null != ndata.email)	email = ndata.email;
			if(null != ndata.limit_storage)	limit_storage = ndata.limit_storage;
			if(null != ndata.storage_used)	storage_used = ndata.storage_used;
			if(null != ndata.limit_uploadspeed)	limit_uploadspeed = ndata.limit_uploadspeed;
			if(null != ndata.status)	status = ndata.status;
		};
	};
	
    enum FTYPE{
        FTYPE_FOLDER,
        FTYPE_FILE;
    };
	BContext contxt = new BContext();
	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        /* init xml parser */
        try{
	        SAXParserFactory spf = SAXParserFactory.newInstance(); 
	        SAXParser sp = spf.newSAXParser(); 
	        xr = sp.getXMLReader(); 
	        xr.setContentHandler((ContentHandler) dataHandler); 
        } catch(ParserConfigurationException pce) { 
            Log.e("SAX XML", "sax parse error", pce); 
        } catch(SAXException se) { 
            Log.e("SAX XML", "sax error", se); 
        } 
        
        Button but_login = (Button)findViewById(R.id.button1);
        but_login.setOnClickListener(backby_Login);
        
        Button but_GetUsedSpace = (Button)findViewById(R.id.button2);
        but_GetUsedSpace.setOnClickListener(backby_GetStorageInfo);
        
        Button but_Upload = (Button)findViewById(R.id.button3);
        but_Upload.setOnClickListener(backby_Upload);   
        
        Button but_Download = (Button)findViewById(R.id.button4);
        but_Download.setOnClickListener(backby_Download);
    }
	
    private void backby_log(String inbuf){
        if(true == DEBUG)
        {
        	Log.v("backby_log",inbuf);
        }
    }
    private void backby_savetofile(String inbuf){
		try {
			FileOutputStream fos = openFileOutput(this.FILENAME, Context.MODE_WORLD_WRITEABLE);
	    	fos.write(inbuf.getBytes());
			fos.flush();
	    	fos.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		backby_log(inbuf);
    }
	private String backby_getfile(){
		String data="";
		try {
			FileInputStream fis = openFileInput(this.FILENAME);
			if(null == fis)
			{
				backby_log("backby_getfile() open file fail!");
				return data;
			}
			StringBuffer sb = new StringBuffer();
			int c;

			while ((c = fis.read()) != -1) 
			{
			    sb.append((char) c);
			}
			fis.close();
			data = sb.toString();

			fis.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return data;
	}

    private void backby_httppost(List<NameValuePair> params){
    	HttpPost request = new HttpPost("http://app.backby.com/client.php");
    	try {
			request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
//			backby_log(request.getRequestLine().toString());
			HttpResponse response = new DefaultHttpClient().execute(request);
			if(response.getStatusLine().getStatusCode() == 200){
				String result = EntityUtils.toString(response.getEntity());
				backby_savetofile(result);
				Toast.makeText(BackbyActivity.this, result, Toast.LENGTH_LONG).show();
			}
		} catch (Exception e) {

			Toast.makeText(BackbyActivity.this, e.getMessage().toString(), Toast.LENGTH_LONG).show();
			e.printStackTrace();
		}
    }
    private boolean backby_login(String name, String pwd){
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		
		params.add(new BasicNameValuePair("ACTION", "login"));
		params.add(new BasicNameValuePair("ACCOUNT",name));
		params.add(new BasicNameValuePair("PASSWORD",pwd));
		backby_httppost(params);
		
		try {
			xr.parse(new InputSource(new StringBufferInputStream(backby_getfile())));
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} 
		
		contxt.updateData(dataHandler.getData());
		if(contxt.resultid.equals("200"))
		{
			return true;
		}
		else
		{
			return false;
		}
    }
    private boolean backby_getstorageinfo(){
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		
		if(null == contxt.sessionid)
		{
			return false;
		}
		
		params.add(new BasicNameValuePair("ACTION", "getStorageInfo"));
		params.add(new BasicNameValuePair("SESSIONID",contxt.sessionid));

		backby_httppost(params);
		
		try {
			xr.parse(new InputSource(new StringBufferInputStream(backby_getfile())));
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} 
		contxt.updateData(dataHandler.getData());
		
		if(contxt.resultid.equals("200"))
		{
			return true;
		}
		else
		{
			return false;
		}
    }
	private boolean backby_list(String folderpath, String page_number){
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		
		if(null == contxt.sessionid)
		{
			backby_log("backby_list sessionid is null");
			return false;
		}
		params.add(new BasicNameValuePair("ACTION", "list"));
		params.add(new BasicNameValuePair("SESSIONID",contxt.sessionid));
		params.add(new BasicNameValuePair("FOLDERKEY",folderpath));
		params.add(new BasicNameValuePair("PAGENUM",page_number));

		backby_httppost(params);
		
		try {
			xr.parse(new InputSource(new StringBufferInputStream(backby_getfile())));
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} 
		contxt.updateData(dataHandler.getData());
		
		if(contxt.resultid.equals("200"))
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	private boolean backby_upload(FTYPE ftype, String todo){
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		String type;
		
		if(null == contxt.sessionid)
		{
			return false;
		}
		switch(ftype)
		{
			case FTYPE_FILE:
				type = "file";
				break;
			case FTYPE_FOLDER:
				type = "folder";
				break;
			default:
				backby_log("backby_upload FTYPE error!");
				return false;
		}
		/*
		params.add(new BasicNameValuePair("ACTION", "write"));
		params.add(new BasicNameValuePair("SESSIONID",contxt.sessionid));
		params.add(new BasicNameValuePair("FOLDERKEY",name));
		params.add(new BasicNameValuePair("TYPE",type));
		params.add(new BasicNameValuePair("NAME",name));
		params.add(new BasicNameValuePair("PARTS",pwd));
		params.add(new BasicNameValuePair("SIZE",name));
*/
		backby_httppost(params);
		
		try {
			xr.parse(new InputSource(new StringBufferInputStream(backby_getfile())));
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} 
		contxt.updateData(dataHandler.getData());
		
		if(contxt.resultid.equals("200"))
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	private boolean backby_download(){
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		
		params.add(new BasicNameValuePair("ACTION", "login"));
//		params.add(new BasicNameValuePair("ACCOUNT",name));
//		params.add(new BasicNameValuePair("PASSWORD",pwd));
		backby_httppost(params);
		
		try {
			xr.parse(new InputSource(new StringBufferInputStream(backby_getfile())));
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} 
		contxt.updateData(dataHandler.getData());
		
		if(contxt.resultid.equals("200"))
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	    
    public class DataHandler extends DefaultHandler { 
		// booleans that check whether it's in a specific tag or not 
    	private boolean _inResult, _inSession, _inAttribute;
		private boolean  _inEMail, _inlimit_storage, _instorage_used, _inlimit_uploadspeed, _instatus; 

		// this holds the data 
		private BContext _data; 

		/** 
		* Returns the data object 
		* 
		* @return 
		*/ 
		public BContext getData() 
		{ 
		    return _data; 
		} 

		/** 
		* This gets called when the xml document is first opened 
		* 
		* @throws SAXException 
		*/ 
		@Override 
		public void startDocument() throws SAXException { 
			_data = new BContext(); 
		} 

		/** 
		* Called when it's finished handling the document 
		* 
		* @throws SAXException 
		*/ 
		@Override 
		public void endDocument() throws SAXException { 

		} 

		/** 
		* This gets called at the start of an element. Here we're also setting the booleans to true if it's at that specific tag. (so we 
		* know where we are) 
		* 
		* @param namespaceURI 
		* @param localName 
		* @param qName 
		* @param atts 
		* @throws SAXException 
		*/ 
		@Override 
		public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { 
			if(localName.equals("Result")) 
			{ 
				_inResult = true; 
				_data.resultid = atts.getValue("id");
			} 
			else if(localName.equals("Session")) 
			{ 
				if(_inResult)
				{
					_inSession = true; 
					if(_data.resultid.equals("200"))
					{
						_data.sessionid = atts.getValue("id");
					}
				}
			}
			else if(localName.equals("Attribute"))
			{
				if(_inResult)
				{
					_inAttribute = true;
					if(_data.resultid.equals("200"))
					{
						if(atts.getValue("name").equals("EMail"))
						{
							_inEMail = true;
						}
						else if(atts.getValue("name").equals("Limit.Storage"))
						{
							_inlimit_storage = true;
						}
						else if(atts.getValue("name").equals("Storage.Used"))
						{
							_instorage_used = true;
						}
						else if(atts.getValue("name").equals("Limit.UploadSpeed"))
						{
							_inlimit_uploadspeed = true;
						}
						else if(atts.getValue("name").equals("Status"))
						{
							_instatus = true;
						}
					}
				}
			}
		} 

		/** 
		* Called at the end of the element. Setting the booleans to false, so we know that we've just left that tag. 
		* 
		* @param namespaceURI 
		* @param localName 
		* @param qName 
		* @throws SAXException 
		*/ 
		@Override 
		public void endElement(String namespaceURI, String localName, String qName) throws SAXException { 
			if(localName.equals("Result")) 
			{ 
				_inResult = false; 
			} 
			else if(localName.equals("Session")) 
		    { 
				_inSession = false; 
			} 
			else if(localName.equals("Attribute"))
			{
				_inEMail = false; 
				_inlimit_storage = false; 
				_instorage_used = false; 
				_inlimit_uploadspeed = false; 
				_instatus = false; 
			}
		} 

		/** 
		* Calling when we're within an element. Here we're checking to see if there is any content in the tags that we're interested in 
		* and populating it in the Config object. 
		* 
		* @param ch 
		* @param start 
		* @param length 
		*/ 
		@Override 
		public void characters(char ch[], int start, int length) { 
			String chars = new String(ch, start, length); 
		    chars = chars.trim(); 
		 
		    if(_inEMail) 
		    { 
		    	_data.email = chars; 
		    } 
		    else if(_inlimit_storage) 
		    { 
		    	_data.limit_storage = chars; 
		    } 
		    else if(_instorage_used) 
		    { 
		    	_data.storage_used = chars; 
		    } 
		    else if(_inlimit_uploadspeed) 
		    { 
		    	_data.limit_uploadspeed = chars; 
		    } 
		    else if(_instatus) 
		    { 
		    	_data.status = chars; 
		    } 
		} 
	} 
	
    private OnClickListener backby_Login = new OnClickListener(){
    	public void onClick(android.view.View arg0) {
    		EditText logname = (EditText)findViewById(R.id.editText1);
    		EditText logpasswd = (EditText)findViewById(R.id.editText2);
    		
    		if(backby_login(logname.getText().toString(),logpasswd.getText().toString()))
    		{
    			((TextView)findViewById(R.id.textView4)).setText("Login is success!");
    		}
    		else
    		{
    			((TextView)findViewById(R.id.textView4)).setText("Login is failed!");
    		}
    	}
    };
    
    private OnClickListener backby_GetStorageInfo = new OnClickListener(){
    	public void onClick(android.view.View arg0) {
    		if(backby_getstorageinfo())
    		{
    			((TextView)findViewById(R.id.textView4)).setText("Get Storage info is success!");
    			((TextView)findViewById(R.id.textView7)).setText(Long.toString(Long.valueOf(contxt.storage_used)/1024/1024/1024)+"GB");
    			((TextView)findViewById(R.id.textView9)).setText(Long.toString(Long.valueOf(contxt.limit_storage)/1024/1024/1024)+"GB");
    		}
    		else
    		{
    			((TextView)findViewById(R.id.textView4)).setText("Get Storage info is failed!");
    		}
    	}
    };
    
    private OnClickListener backby_Upload = new OnClickListener(){
    	public void onClick(android.view.View arg0) {
    		/*
    		if(backby_upload())
    		{
    			((TextView)findViewById(R.id.textView4)).setText("Upload is success!");
    		}
    		else
    		{
    			((TextView)findViewById(R.id.textView4)).setText("Upload is failed!");
    		}
    		*/
    	}
    };
    
    private OnClickListener backby_Download = new OnClickListener(){
    	public void onClick(android.view.View arg0) {
		backby_list("/","");	
		/*
    		if(backby_download())
    		{
    			((TextView)findViewById(R.id.textView4)).setText("Download is success!");
    		}
    		else
    		{
    			((TextView)findViewById(R.id.textView4)).setText("Download is failed!");
    		}
    		*/
    	}
    };
}
